package com.decade.mapper.impl;

import com.decade.mapper.GoodsDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.sql.DataSource;
import java.sql.*;
import java.util.*;

@Repository
public class DefaultGoodsDao implements GoodsDao {
    @Autowired
    private DataSource dataSource;

    //初始化一个日志对象（所有类都在org.slf4j包中）
    //在那个类创建日志对象，我们的getLogger方法内部的对象就为哪个类的字节码对象
    private static final Logger log =
            LoggerFactory.getLogger(DefaultGoodsDao.class);

    //封装结果集
    public Map<String,Object> getMapEntity(ResultSetMetaData rm ,ResultSet rs) throws SQLException {
        Map<String,Object> map = new HashMap<>();
        for(int i=1;i<rm.getColumnCount();i++){
            map.put(rm.getColumnClassName(i), rs.getObject(i));
        }
        return map;
    }

    //封装资源的关闭
    public void closes(ResultSet rs,PreparedStatement ps,Connection conn){
        try {
            if(rs!=null)rs.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if(ps!=null)ps.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        try {
            if(conn!=null)conn.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @Override
    public List<Map<String,Object>> findAll() {
        System.out.println("ddd");
        Connection conn = null;
        String sql = "select * from tb_goods";
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = dataSource.getConnection();

            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            List<Map<String,Object>> list = new ArrayList<>();
            ResultSetMetaData metaData = rs.getMetaData();

            while (rs.next()){
//                Map<String,Object> map = new HashMap<>();
//                Integer id = rs.getInt("id");
//                String name = rs.getString("name");
//                String remark = rs.getString("remark");
//                Date createdTime = (Date) rs.getObject("createdTime");
//                map.put("id", id);
//                map.put("name", name);
//                map.put("remark", remark);
//                map.put("createdTime", createdTime);
                //封装map
                Map<String,Object> map = getMapEntity(metaData,rs);
                list.add(map);
            }
            return list;
        }catch (SQLException e){
            e.printStackTrace();
            //记录日志（一般异常日志借助log.error方法进行记录）
            log.error("{查询异常，{}",e.getMessage());//{}表示占位符
        }finally {
            closes(rs, ps, conn);
        }

        return null;
    }
}

/**
 * 对于如上查询商品数据的过程有什么优缺点？
 * 优点：
 * 1）使用了连接池，优化了建立连接的过程，从池中获取连接，提高了数据访问性能。
 * 2）代码简单（就是一些流水代码，步骤固定）
 * 3）使用了map做映射，简化pojo对象定义
 * 缺点：
 * 1）可重用性比较差（例如释放资源代码，完全可以封装）
 * 2）行映射不够灵活，过于僵硬。
 * 3）异常的处理不能简单打印一下，然后返回一个null就可以了
 * 4）map封装数据时值类型不可控（建议后续修改为pojo对象 ）
 * 5）对共性模板应该进行封装，特性代码进行提取
 * */